﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Interfaces;
using BusinessObjects;
using DataAccess;
using DCMSExceptions;
using System.Data;

namespace BusinessLogic {

  /// <summary>
  /// Business Logic Layer for children
  /// </summary>
  public class ChildrenBll : IChildrenLogic {

    private ChildrenDal dal = new ChildrenDal( );

    #region - Public methods -

    /// <summary>
    /// Gets the children.
    /// </summary>
    /// <param name="allChildren">if set to <c>true</c> [all children].</param>
    /// <returns></returns>
    public Children GetChildren( bool allChildren ) {
      Children children;
      try {
        children = dal.GetChildren( allChildren );
      } catch ( DataException ex ) {
        throw new BusinessException( "Fout bij ophalen kinderen.", ex );
      }
      return children;
    }

    /// <summary>
    /// Gets the child.
    /// </summary>
    /// <param name="childId">The child id.</param>
    /// <returns></returns>
    public Child GetChild( int childId ) {
      Child child;
      try {
        child = dal.GetChild( childId );
      } catch ( DataException ex ) {
        throw new BusinessException( "Fout bij ophalen kind.", ex );
      }
      return child;
    }

    /// <summary>
    /// Saves the children.
    /// </summary>
    /// <param name="children">The children.</param>
    public void SaveChildren( Children children ) {
      bool valid = true;
      foreach ( Child child in children ) {
        if ( !Validate( child ) ) {
          valid = false;
          break;
        }
      }
      if ( valid ) {
        try {
          dal.SaveChildren( children );
        } catch ( DataException ex ) {
          throw new BusinessException( "Fout bij bewaren van kinderen.", ex );
        }
      }

    }

    /// <summary>
    /// Saves the child.
    /// </summary>
    /// <param name="child">The child.</param>
    public void SaveChild( Child child ) {

      if ( Validate( child ) ) {
        try {
          dal.SaveChild( child );
        } catch ( DataException ex ) {
          throw new BusinessException( ex.Message, ex );
        }
      } else {
        throw new BusinessException( child.BrokenRulesMessages );
      }

    }

    /// <summary>
    /// Deletes the specified child.
    /// </summary>
    /// <param name="child">The child.</param>
    public void Delete( Child child ) {

      Children linkedChildren = dal.GetLinkedChildren( child.Id );
      if ( linkedChildren.Count > 0 ) {
        StringBuilder sb = new StringBuilder( "Kind is nog gekoppeld aan: \n" );
        foreach ( Child link in linkedChildren ) {
          sb.Append( link.FirstName + " " + link.Name + " \n" );
        }
        throw new BusinessException( sb.ToString( ) );
      } else {
        try {
          dal.Delete( child );
        } catch ( Exception ex ) {
          throw new BusinessException( ex.Message, ex );
        }
      }

    }

    #endregion

    private bool Validate( Child child ) {
      child.ClearBrokenRules( );

      if ( string.IsNullOrEmpty( child.Name ) ) {
        child.AddBrokenRule( "EmptyName", "Naam is niet ingevuld." );
      }

      if ( child.Mother.MainAddress && child.Father.MainAddress ) {
        child.AddBrokenRule( "SingleMainAddress", "Slechts 1 hoofdadres." );
      }

      if ( !child.Mother.MainAddress && !child.Father.MainAddress ) {
        child.AddBrokenRule( "MainAddressMissing", "Geen hoofdadres gekozen." );
      }

      if ( child.Mother.MainAddress && !child.Father.MainAddress) {
        if ( string.IsNullOrEmpty( child.Mother.Name ) ) {
          child.AddBrokenRule( "EmptyMotherName", "Naam moeder niet ingevuld." );
        }

        if ( string.IsNullOrEmpty( child.Mother.Phone ) && string.IsNullOrEmpty( child.Mother.Gsm ) ) {
          child.AddBrokenRule( "MotherPhone", "Telefoon of GSM niet ingevuld." );
        }
      }

      if ( child.Father.MainAddress && !child.Mother.MainAddress ) {
        if ( string.IsNullOrEmpty(child.Father.Name) ) {
          child.AddBrokenRule( "EmptyFatherName", "Naam vader niet ingevuld." );
        }

        if ( string.IsNullOrEmpty(child.Father.Phone) && string.IsNullOrEmpty(child.Father.Gsm) ) {
          child.AddBrokenRule( "FatherPhone", "Telefoon of GSM niet ingevuld." );
        }
      }
    
      if ( child.Mother.BasicPrice == 0 ) {
        child.AddBrokenRule( "BasicPrice", "Basis prijs niet ingevuld." );
      }

      switch ( child.Schedule.Type ) {
        case Schedule.ScheduleType.Weekly:
          if ( !child.Schedule.Week1IsSet ) {
            child.AddBrokenRule( "ScheduleWeekly", "Weekelijks schema niet correct ingevuld." );
          }
          break;
        case Schedule.ScheduleType.Twoweekly:
          if ( !child.Schedule.Week1IsSet && !child.Schedule.Week2IsSet ) {
            child.AddBrokenRule( "ScheduleTwoWeekly", "2-weeklelijks schema niet correct ingevuld." );
          }
          break;
        case Schedule.ScheduleType.Monthly:
          if ( !child.Schedule.Week1IsSet && !child.Schedule.Week2IsSet && !child.Schedule.Week3IsSet && !child.Schedule.Week4IsSet ) {
            child.AddBrokenRule( "ScheduleMonthly", "Maandelijks schema niet correct ingevuld." );
          }
          break;
        case Schedule.ScheduleType.Variable:
          break;
        default:
          break;
      }

      return child.IsValid;
    }

  }
}
